/* Copyright (C) 2008  Romolo Camplani, Marco Fortunato, Marco Marelli, Guido Rota, Fabio A. Schreiber et al.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
/*
 * SimulationPerformer.java
 *
 * Created on November 27, 2007, 1:47 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.dei.perla.utils.emulator.runtime;

import java.io.*;
import java.net.*;
import java.util.*;

import org.dei.perla.utils.emulator.model.node.Node;
import org.dei.perla.utils.emulator.models.world.Position;

/**
 *
 * @author Adnan
 */


public class SimulationPerformer {
   // ServerSocket ss;
  //  Socket sock;
    static int x=0;
    ArrayList<Node> nodes;
    SimulationPerformerMDB spmdb;
    ArrayList<PrintWriter> clientOutputStreams;
    PrintWriter writer;
    /** Creates a new instance of SimulationPerformer */
    public SimulationPerformer(ArrayList<Node> tnodes) {
        
        spmdb = new ModelDescriptionBuilder();
        nodes = tnodes;
        clientOutputStreams = new ArrayList<PrintWriter>();
    }
    
    public void go()
    {
    
        System.out.println("I am in simulation performer.");
     
        
        try
        {
            // a socket for giving continuos feedback of the sensor environment
             ServerSocket ss = new ServerSocket(4020); 
             
            // a socket to take input from a third party software
             ServerSocket ss2 = new ServerSocket(4021); 
             
        
            while (true)
            {
         //        System.out.println("Waiting to accept feedback Socket ...");
                 Socket feedbackSocket = ss.accept();
         //        System.out.println("Hurray! She has accepted feedbackSocket!.");
                 Thread t = new Thread(new ContinuousFeedbackThread(feedbackSocket));
                 t.start();
                
       //          System.out.println("Waiting to accept input Socket ...");
                 Socket inputSocket = ss2.accept();
       //          System.out.println("Hurray! She has accepted inputSocket!.");
                 Thread t2 = new Thread(new InputThread(inputSocket));
                 t2.start();
                        
            }
        
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    // We create the Thread Job class namely ContinuousFeedBackThread" as an inner class 
    
final class ContinuousFeedbackThread implements Runnable
 {
    Socket sock;
    public ContinuousFeedbackThread(Socket sock) throws Exception
    {
        this.sock = sock;
    }
    public void run(){
   
        try{
            
            while(true)
            {
             //   if (x++ == 10) break;
                Thread.sleep(1000);
                 doItNow();
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        
       
     }
   
    public  void doItNow() throws Exception
    {
 //       if(nodes.isEmpty()) 
 //                     System.out.println("tnodes is empty in server socket");
       
        PrintWriter writer = 
                      new PrintWriter(this.sock.getOutputStream());
        
        writer.println(" ");    
        boolean nodeFound = false;
        nodes = spmdb.getLivingNodes(nodes);
        for (Node tnode:nodes)
                {
                    Position p = tnode.getPosition();
                   
                    String nodeStatus = "Node id = " + tnode.getID()+ "; " +
                                        "Node position = " + p.getX()+ ", " + p.getY() + ", " + ";" +
                                        "Node charge = " + tnode.getCharge()+ "." ;
                    
                    nodeFound = true;
                    writer.println(nodeStatus);
                    System.out.println("Wrote: "+nodeStatus);
                    writer.flush();
                    
                }
        if(!nodeFound) System.out.println("No node information to print");
        System.out.println("");
    }
  }

// We create the Thread Job class namely InputThread as an inner class 
final class InputThread implements Runnable
 {
    Socket sock;
    InputInterface ii;
    public InputThread(Socket sock) throws Exception
    {
        this.sock = sock;
        ii = new InputInterface();
    }
    public void run(){
   
        try{
            
            while(true)
            {
            //    if (y++ == 10) break;
                Thread.sleep(1000);
                 doItNow();
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        
       
     }
   
    public  void doItNow() throws Exception
    {
        InputStreamReader isr = new InputStreamReader(sock.getInputStream());
        BufferedReader br = new BufferedReader(isr);
        
        while(true)
        {
            String str = br.readLine();
            ArrayList<Node> tnodes = ii.processStringForThirdParty(nodes, str); 
            nodes = tnodes;
            
        }
        
    }
  }
}


    


